/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.views.impl;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.AppServiceFileUtils;
import cn.easyplatform.studio.utils.FileUtil;
import cn.easyplatform.studio.utils.StudioServiceFileUtils;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.utils.resource.GResource;
import cn.easyplatform.utils.resource.Scans;
import com.alibaba.fastjson.JSON;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.apache.commons.lang3.StringUtils;
import org.zkoss.image.AImage;
import org.zkoss.util.resource.Labels;
import org.zkoss.util.resource.Locators;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zul.*;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
class IconView extends AbstractView<String> {

	private String scope;

	private Bandbox searchBandbox;

	private Button uploadButton;

	private Grid iconGrid;

    private Grid imageGrid;

    private Grid uploadGrid;

	private Tabbox tabbox;

	private final static List<String> imageFilenames = new ArrayList<String>();

	private static List<String> allIconList = new ArrayList<String>();

	static {
		List<GResource> grList = Scans.me().scan("web/images",
				"^.+[\\.gif|\\.png]$");
		for (GResource gr : grList) {
			if (StringUtils.countMatches(gr.getName(), "/") == 1)
				imageFilenames.add(gr.getName().substring(1));
		}
		grList.clear();
		grList = null;

		InputStream inputStream = Locators.getDefault().getResourceAsStream("web/support/zicon.json");
		try {
			String content = IOUtils.toString(inputStream, UTF_8);
			allIconList = JSON.parseArray(content, String.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param cb
	 */
	protected IconView(EditorCallback<String> cb, String scope, Component component) {
		super(component, cb);
		this.scope = scope;
	}

	@Override
	protected void createContent(final Component parent) {
		Component component = Executions.createComponents(
				"~./include/views/icons.zul", parent, null);

		Div c = (Div) component.getFellow("icons_div_main");

		searchBandbox = (Bandbox) component.getFellow("icons_bandbox_search");
		searchBandbox.addEventListener(Events.ON_CHANGE, this);
		searchBandbox.addEventListener(Events.ON_OPEN, this);
		searchBandbox.addEventListener(Events.ON_OK, this);

		uploadButton = (Button) component.getFellow("icons_button_upload");
		uploadButton.addEventListener(Events.ON_UPLOAD, this);

		iconGrid = (Grid) component.getFellow("icons_grid_icon");
		if (scope.equals("icon") || scope.equals("*")) {
			uploadButton.setVisible(false);
			redrawIconGrid(allIconList);
		}
		if (scope.equals("image")) {
			c.getChildren().clear();
		}
		if (scope.equals("*") || scope.equals("image")) {
			Grid iconGrid = null;
			if (scope.equals("*")){
				iconGrid = (Grid) c.query("grid");
				iconGrid.setPageSize(5);
				c.getChildren().clear();
			}
			tabbox = new Tabbox();
			tabbox.setId("icons_tabbox_iconType");
			tabbox.addEventListener(Events.ON_SELECT, this);
			tabbox.setVflex("1");
			tabbox.setHflex("1");
			Tabs tabs = new Tabs();
			tabs.setId("tabs");
			tabbox.appendChild(tabs);
			Tabpanels tabpanels = new Tabpanels();
			tabpanels.setId("tabpanels");
			tabbox.appendChild(tabpanels);
			c.appendChild(tabbox);
			if (scope.equals("*")){
				Tab tabIcon = new Tab("z-icons");
				tabbox.getFellow("tabs").appendChild(tabIcon);
				Tabpanel tpIcon = new Tabpanel();
				tabbox.getFellow("tabpanels").appendChild(tpIcon);
				tpIcon.appendChild(iconGrid);
			}
			Tab tab = new Tab(Labels.getLabel("editor.file.img.systemList"));
			tabbox.getFellow("tabs").appendChild(tab);
			imageGrid = new Grid();
			imageGrid.setId("icons_grid_image");
            imageGrid.setHflex("1");
            imageGrid.setVflex("1");
            imageGrid.setSclass("epview-icons");
            imageGrid.setMold("paging");
            imageGrid.setPageSize(5);
            imageGrid.appendChild(new Rows());
			redrawImageGrid(imageFilenames);

			Tabpanel tp = new Tabpanel();
			tabbox.getFellow("tabpanels").appendChild(tp);
			tp.appendChild(imageGrid);

			FileUtil.mkdirForNoExists(new AppServiceFileUtils().imgDirPath_app);
			List<String> fileName = Arrays.asList(new File(new AppServiceFileUtils().imgDirPath_app).list());
			if (fileName != null && fileName.size() != 0) {
				Tab uploadTab = new Tab(Labels.getLabel("editor.file.img.uploadList"));
				tabbox.getTabs().appendChild(uploadTab);
				uploadGrid = new Grid();
				uploadGrid.setId("icons_grid_upload");
				uploadGrid.setHflex("1");
				uploadGrid.setVflex("1");
				uploadGrid.setSclass("epview-icons");
				uploadGrid.setMold("paging");
				uploadGrid.setPageSize(5);
				uploadGrid.appendChild(new Rows());
				redrawUploadGrid(fileName);

				Tabpanel uploadTp = new Tabpanel();
				tabbox.getTabpanels().appendChild(uploadTp);
				uploadTp.appendChild(uploadGrid);
			}
			Window window = (Window) parent.getParent().getParent();
			window.setHeight("480px");
		}
		Iterator<Component> itr = c.queryAll("vlayout").iterator();
		while (itr.hasNext()) {
			itr.next().addEventListener(Events.ON_DOUBLE_CLICK, this);
		}

		//将项目名传入servlet，获取apps路径渲染图片
		searchBandbox.getDesktop().getSession().setAttribute("projectName", Contexts.getProject().getId());
	}

	@Override
	public void onEvent(Event event) throws Exception {
		if (event.getTarget() instanceof Vlayout) {
			List<Component> comps = event.getTarget().getChildren();
			boolean isA = false;
			boolean isImage = false;
			Component currentComp = null;
			for (Component comp : comps) {
				if (comp instanceof A) {
					isA = true;
					currentComp = comp;
				}
				else if (comp instanceof Image) {
					isImage = true;
					currentComp = comp;
				}
			}

			if (isA == true) {
				A a = (A) currentComp;
				if (!Strings.isBlank(a.getIconSclass()))
					cb.setValue(a.getIconSclass());
				else
					cb.setValue("~./images/" + a.getTooltiptext());
				event.getTarget().getRoot().detach();
			} else if (isImage == true) {
				Image image = (Image) currentComp;
				if (image.getSrc() != null)
					cb.setValue(image.getSrc());
				else
					cb.setValue("/apps/" + Contexts.getProject().getId() + "/img/" + image.getContent().getName());
				event.getTarget().getRoot().detach();
			}
			onCloseClick(win);
		}
		if (tabbox != null && event.getTarget() instanceof Tab) {
			searchBandbox.setValue(null);
			boolean isIcon = scope.equals("icon") ||
					(tabbox != null && tabbox.getSelectedIndex() == 0 && scope.equals("*"));
			boolean isImage = (tabbox != null && scope.equals("image") && tabbox.getSelectedIndex() == 0 )||
					(tabbox != null && tabbox.getSelectedIndex() == 1 && scope.equals("*"));
			boolean isUpload = (tabbox != null && scope.equals("image") && tabbox.getSelectedIndex() == 1 )||
					(tabbox != null && tabbox.getSelectedIndex() == 2 && scope.equals("*"));
			if (isIcon) {
				redrawIconGrid(allIconList);
			} else if (isImage) {
				redrawImageGrid(imageFilenames);
			} else if (isUpload) {
				List<String> fileName = Arrays.asList(new File(new AppServiceFileUtils().imgDirPath_app).list());
				redrawUploadGrid(fileName);
			}
		}
		if (event.getTarget().equals(searchBandbox)) {
			if (event instanceof OpenEvent  || event.getName().equals(Events.ON_OK)) {
				String val;
				if (event instanceof OpenEvent){
					OpenEvent evt = (OpenEvent) event;
					val = (String) evt.getValue();
				}else {
					val = searchBandbox.getValue();
				}
				searchBandbox.setValue(val);
				boolean isIcon = scope.equals("icon") ||
                        (tabbox != null && tabbox.getSelectedIndex() == 0 && scope.equals("*"));
                boolean isImage = (tabbox != null && scope.equals("image") && tabbox.getSelectedIndex() == 0 )||
                        (tabbox != null && tabbox.getSelectedIndex() == 1 && scope.equals("*"));
                boolean isUpload = (tabbox != null && scope.equals("image") && tabbox.getSelectedIndex() == 1 )||
                        (tabbox != null && tabbox.getSelectedIndex() == 2 && scope.equals("*"));
				if (isIcon) {
					if (Strings.isBlank(val))
						redrawIconGrid(allIconList);
					else {
						List<String> iconNameList = new ArrayList<>();
						for (String iconName : allIconList) {
							if (iconName.contains(val) == true)
								iconNameList.add(iconName);
						}
						redrawIconGrid(iconNameList);
					}
				} else if (isImage) {
					if (Strings.isBlank(val))
                        redrawImageGrid(imageFilenames);
					else {
						List<String> imageNameList = new ArrayList<>();
						for (String iconName : imageFilenames) {
							if (iconName.contains(val) == true)
                                imageNameList.add(iconName);
						}
						redrawImageGrid(imageNameList);
					}
				} else if (isUpload) {
					List<String> fileName = Arrays.asList(new File(new AppServiceFileUtils().imgDirPath_app).list());
                    if (Strings.isBlank(val)) {
                        redrawUploadGrid(fileName);
                    } else {
						List<String> imageNameList = new ArrayList<>();
                        for (String uploadName : fileName) {
                            if (uploadName.contains(val) == true)
                                imageNameList.add(uploadName);
                        }
                        redrawUploadGrid(imageNameList);
                    }
                }
			}
		}
		if (event.getTarget().equals(uploadButton)) {
			UploadEvent evt = (UploadEvent) event;
			org.zkoss.util.media.Media media = evt.getMedia();
			String dirPath_app = new AppServiceFileUtils().imgDirPath_app;
			try {
				String mediaPath_apps = dirPath_app + File.separator + media.getName();
				FileUtils.copyInputStreamToFile(media.getStreamData(), new File(mediaPath_apps));
				WebUtils.showSuccess(Labels.getLabel("editor.file.upload"));
			} catch (IOException e) {
				WebUtils.showError(Labels.getLabel("message.error", new String[]{Labels.getLabel("editor.file.upload")}));
				e.printStackTrace();
			}
			List<String> fileName = Arrays.asList(new File(new AppServiceFileUtils().imgDirPath_app).list());
			redrawUploadGrid(fileName);
		}
	}


	private void redrawIconGrid(List<String> iconList) {
		iconGrid.getRows().getChildren().clear();
		Row row = null;
		for (int index = 0; index < iconList.size(); index++) {
			if (index % 6 == 0) {
				row = new Row();
			}
			Vlayout vlayout = new Vlayout();

			A iconA = new A();
			iconA.setIconSclass(iconList.get(index));
			vlayout.appendChild(iconA);

			Label iconLabel = new Label();
			iconLabel.setValue(iconList.get(index));
			vlayout.appendChild(iconLabel);
			vlayout.addEventListener(Events.ON_DOUBLE_CLICK, this);

			row.appendChild(vlayout);
			if (index % 6 == 5|| index == iconList.size() - 1) {

				iconGrid.getRows().appendChild(row);
			}
		}
	}

	private void redrawImageGrid(List<String> imageList) {
        imageGrid.getRows().getChildren().clear();
		Row row = null;
		for (int i = 0; i < imageList.size(); i++) {
			if (i % 6 == 0)
				row = new Row();
			Vlayout vlayout = new Vlayout();

			A a = new A();
			a.setTooltiptext(imageList.get(i));
			a.setImage("~./images/" + imageList.get(i));
			vlayout.appendChild(a);

			Label nameLabel = new Label();
			nameLabel.setValue(imageList.get(i));
			vlayout.appendChild(nameLabel);
			vlayout.addEventListener(Events.ON_DOUBLE_CLICK, this);

			row.appendChild(vlayout);
            imageGrid.getRows().appendChild(row);
		}
	}

	private void redrawUploadGrid(List<String> fileName) {
        uploadGrid.getRows().getChildren().clear();
        Row uploadRow = null;
        for (int i = 0; i < fileName.size(); i++) {
            if (i % 6 == 0)
                uploadRow = new Row();
            Vlayout vlayout = new Vlayout();

            Image image = new Image();
            image.setStyle("max-height: 30px;max-width: 120px;");
            image.setTooltiptext(fileName.get(i));
            if (!isContainChinese(fileName.get(i))) {
				image.setSrc("template/public/img/" + fileName.get(i));
            } else {
                try {
                    image.setContent(new AImage(fileName.get(i), new FileInputStream(
                    		StudioApp.getServletContext().getRealPath(
                    				"/apps/" + Contexts.getProject().getId() + "/img") + File.separator + fileName.get(i))));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

			vlayout.appendChild(image);
            Label nameLabel = new Label();
            nameLabel.setValue(fileName.get(i));
            vlayout.appendChild(nameLabel);
			vlayout.addEventListener(Events.ON_DOUBLE_CLICK, this);

            uploadRow.appendChild(vlayout);
            uploadGrid.getRows().appendChild(uploadRow);
        }
    }

	private boolean isContainChinese(String str) {
		Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
		Matcher m = p.matcher(str);
		if (m.find()) {
			return true;
		}
		return false;
	}

}
